package vip.xiaonuo.devicebase;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.RBucket;
import org.redisson.api.RList;
import org.redisson.api.RedissonClient;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
import vip.xiaonuo.constant.ThreeSidesConstant;
import vip.xiaonuo.core.context.constant.ConstantContextHolder;
import vip.xiaonuo.core.timer.TimerTaskRunner;
import vip.xiaonuo.core.util.DateUtils;
import vip.xiaonuo.facedoor.modular.devicebase.entity.DeviceBase;
import vip.xiaonuo.facedoor.modular.devicebase.service.DeviceBaseService;
import vip.xiaonuo.facedoor.modular.devicehistory.entity.DeviceHistory;
import vip.xiaonuo.facedoor.modular.devicehistory.service.DeviceHistoryService;
import vip.xiaonuo.facedoor.modular.message.Topic;
import vip.xiaonuo.facedoor.modular.util.ImageToBase64;

import javax.annotation.Resource;
import java.io.File;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

@Component
@Slf4j
public class DeviceBasePushTask implements TimerTaskRunner {

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Resource
    private DeviceBaseService deviceBaseService;

    @Resource
    private RedissonClient redissonClient;

    private static final String TASK_LOCK = "dw_device_base_tx";
    private static final String TABLE_NAME = "dw_device_base";


    @Override
    public void action(String jobParams, String taskId) {
        String dept_code = ConstantContextHolder.getSysConfig("DEPT_CODE", String.class, true);
        String tenantCode = ConstantContextHolder.getSysConfig("TENANT_CODE", String.class, true);
        assert dept_code != null;
        assert tenantCode != null;

        RBucket<String> taskLock = redissonClient.getBucket(TASK_LOCK);
        if (taskLock.isExists()) {
            log.error("当前设备数据正在上报中！稍后上报！");
            return;
        }
        // 数据查询
        List<DeviceBase> list = deviceBaseService.list();


        if (CollectionUtils.isEmpty(list)) {
            log.error("不存在要上报的设备数据");
            return;
        }
        try {
            // 锁task+设置分组
            lockTableAndInit(dept_code, tenantCode, taskLock);

            // rodo 数据转换
            for (DeviceBase deviceBase : list) {
                deviceBase.setTenantCode(tenantCode);
                deviceBase.setDeptCode(dept_code);
            }

            // 发送消息
            sendMessage(list);
        } catch (Exception e) {
            log.error("执行车辆推送任务发生错误【{}】", ExceptionUtil.getMessage(e));
        } finally {
            taskLock.delete();
        }
    }

    private void lockTableAndInit(String dept_code, String tenantCode, RBucket<String> taskLock) {
        // 任务锁
        taskLock.set(DateUtils.getDateTime());

        // 设置生产者组
        rocketMQTemplate.getProducer().setProducerGroup(tenantCode.concat(dept_code));
    }

    private void sendMessage(List<DeviceBase> list) {
        UUID batchId = UUID.randomUUID();

        // 设置消息
        Message<String> message = MessageBuilder.withPayload(JSON.toJSONString(list))
                .setHeader(ThreeSidesConstant.TABLE, TABLE_NAME)
                .setHeader(ThreeSidesConstant.BATCH_ID, batchId.toString())
                .setHeader(ThreeSidesConstant.TASK_LOCK_KEY, TASK_LOCK)
                .build();
        // 直推
        rocketMQTemplate.sendOneWay(Topic.FACEDOOR_DEVICEBASE, message);
    }

    @Override
    @XxlJob("issuedTask")
    public void executeXxlJob() throws InterruptedException {

    }


}
